home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / dev / misc / CWeb31p9b_locale.lha / CWeb / Examples / wmerge.c.save < prev    next >
Encoding:
Text File  |  1993-12-06  |  13.3 KB  |  739 lines

  1. #define buf_size 100 \
  2.  
  3. #define max_include_depth 10 \
  4.  \
  5.  
  6. #define max_file_name_length 256 \
  7.  
  8. #define cur_file file[include_depth]
  9. #define cur_file_name file_name[include_depth]
  10. #define cur_line line[include_depth]
  11. #define web_file file[0]
  12. #define web_file_name file_name[0] \
  13.  
  14. #define lines_dont_match (change_limit-change_buffer!=limit-buffer|| \
  15. strncmp(buffer,change_buffer,limit-buffer) )  \
  16.  
  17. #define PATH_SEPARATOR ','
  18. #define DIR_SEPARATOR '/'
  19. #define DEVICE_SEPARATOR ':' \
  20.  
  21. #define too_long() {include_depth--; \
  22. err_print("! Include file name too long") ;goto restart;} \
  23.  
  24. #define spotless 0
  25. #define harmless_message 1
  26. #define error_message 2
  27. #define fatal_message 3
  28. #define mark_harmless {if(history==spotless) history= harmless_message;}
  29. #define mark_error history= error_message \
  30.  
  31. #define fatal(s,t) { \
  32. fprintf(stderr,s) ;err_print(t) ; \
  33. history= fatal_message;exit(wrap_up() ) ; \
  34. } \
  35.  \
  36.  
  37. #define RETURN_OK 0
  38. #define RETURN_WARN 5
  39. #define RETURN_ERROR 10
  40. #define RETURN_FAIL 20 \
  41.  
  42. #define show_banner flags['b']
  43. #define show_happiness flags['h'] \
  44.  
  45. #define update_terminal fflush(stderr)  \
  46.  \
  47.  
  48. #define MAXPATHLENGTH 4095
  49. #define CWEBINPUTS ",CWeb:,CWeb:include,CWeb:inputs" \
  50.  
  51. /*1:*/
  52. #line 13 "wmerge.w"
  53.  
  54. #line 65 "wmerge.ch"
  55. #include <stdio.h>
  56. #include <string.h>
  57. #line 15 "wmerge.w"
  58. #include <stdlib.h> 
  59. #include <ctype.h> 
  60. /*2:*/
  61. #line 35 "wmerge.w"
  62.  
  63. typedef short boolean;
  64. typedef unsigned char eight_bits;
  65. typedef char ASCII;
  66.  
  67. /*:2*//*5:*/
  68. #line 68 "wmerge.w"
  69.  
  70. ASCII buffer[buf_size];
  71. ASCII*buffer_end= buffer+buf_size-2;
  72. ASCII*limit;
  73. ASCII*loc;
  74.  
  75. /*:5*//*7:*/
  76. #line 134 "wmerge.w"
  77.  
  78. int include_depth;
  79. FILE*file[max_include_depth];
  80. FILE*change_file;
  81. char file_name[max_include_depth][max_file_name_length];
  82.  
  83. char change_file_name[max_file_name_length];
  84. char alt_web_file_name[max_file_name_length];
  85. int line[max_include_depth];
  86. int change_line;
  87. int change_depth;
  88. boolean input_has_ended;
  89. boolean changing;
  90. boolean web_file_open= 0;
  91.  
  92. /*:7*//*8:*/
  93. #line 160 "wmerge.w"
  94.  
  95. char change_buffer[buf_size];
  96. char*change_limit;
  97.  
  98. /*:8*//*23:*/
  99. #line 478 "wmerge.w"
  100.  
  101. int history= spotless;
  102.  
  103. /*:23*//*30:*/
  104. #line 575 "wmerge.w"
  105.  
  106. int argc;
  107. char**argv;
  108. char out_file_name[max_file_name_length];
  109. #line 301 "wmerge.ch"
  110. boolean flags[256];
  111. #line 580 "wmerge.w"
  112.  
  113. /*:30*//*40:*/
  114. #line 692 "wmerge.w"
  115.  
  116. FILE*out_file;
  117.  
  118. /*:40*//*44:*/
  119. #line 374 "wmerge.ch"
  120.  
  121. char include_path[MAXPATHLENGTH+1]= CWEBINPUTS;
  122. char*p,*path_prefix,*next_path_prefix;
  123.  
  124. /*:44*/
  125. #line 17 "wmerge.w"
  126.  
  127. /*4:*/
  128. #line 51 "wmerge.w"
  129.  
  130. #line 52 "wmerge.w"
  131.  
  132. /*:4*//*24:*/
  133. #line 241 "wmerge.ch"
  134.  
  135. #line 242 "wmerge.ch"
  136. void err_print(char*);
  137.  
  138. /*:24*//*32:*/
  139. #line 322 "wmerge.ch"
  140.  
  141. #line 323 "wmerge.ch"
  142. void scan_args(void);
  143.  
  144. /*:32*//*45:*/
  145. #line 381 "wmerge.ch"
  146.  
  147. int get_line(void);
  148. int input_ln(FILE*fp);
  149. int main(int argc,char**argv);
  150. int wrap_up(void);
  151. void check_change(void);
  152. void check_complete(void);
  153. void err_print(char*s);
  154. void prime_the_change_buffer(void);
  155. void put_line(void);
  156. void reset_input(void);
  157. void scan_args(void);
  158. static boolean set_path(char*ptr,char*override);
  159.  
  160.  
  161. /*:45*/
  162. #line 18 "wmerge.w"
  163.  
  164. /*6:*/
  165. #line 93 "wmerge.w"
  166.  
  167. #line 82 "wmerge.ch"
  168. int input_ln(FILE*fp)
  169.  
  170. #line 96 "wmerge.w"
  171. {
  172. register int c= EOF;
  173. register char*k;
  174. if(feof(fp))return(0);
  175. limit= k= buffer;
  176. while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
  177. if((*(k++)= c)!=' ')limit= k;
  178. if(k>buffer_end)
  179. if((c= getc(fp))!=EOF&&c!='\n'){
  180. ungetc(c,fp);loc= buffer;err_print("! Input line too long");
  181.  
  182. }
  183. if(c==EOF&&limit==buffer)return(0);
  184.  
  185. return(1);
  186. }
  187.  
  188. /*:6*//*9:*/
  189. #line 171 "wmerge.w"
  190.  
  191. #line 99 "wmerge.ch"
  192. void prime_the_change_buffer(void)
  193. #line 174 "wmerge.w"
  194. {
  195. change_limit= change_buffer;
  196. /*10:*/
  197. #line 185 "wmerge.w"
  198.  
  199. while(1){
  200. change_line++;
  201. if(!input_ln(change_file))return;
  202. if(limit<buffer+2)continue;
  203. if(buffer[0]!='@')continue;
  204. if(isupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  205. if(buffer[1]=='x')break;
  206. if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
  207. loc= buffer+2;
  208. err_print("! Missing @x in change file");
  209.  
  210. }
  211. }
  212.  
  213. /*:10*/
  214. #line 176 "wmerge.w"
  215. ;
  216. /*11:*/
  217. #line 202 "wmerge.w"
  218.  
  219. do{
  220. change_line++;
  221. if(!input_ln(change_file)){
  222. err_print("! Change file ended after @x");
  223.  
  224. return;
  225. }
  226. }while(limit==buffer);
  227.  
  228. /*:11*/
  229. #line 177 "wmerge.w"
  230. ;
  231. /*12:*/
  232. #line 212 "wmerge.w"
  233.  
  234. {
  235. change_limit= change_buffer-buffer+limit;
  236. strncpy(change_buffer,buffer,limit-buffer+1);
  237. }
  238.  
  239. /*:12*/
  240. #line 178 "wmerge.w"
  241. ;
  242. }
  243.  
  244. /*:9*//*13:*/
  245. #line 230 "wmerge.w"
  246.  
  247. #line 107 "wmerge.ch"
  248. void check_change(void)
  249. #line 233 "wmerge.w"
  250. {
  251. int n= 0;
  252. if(lines_dont_match)return;
  253. while(1){
  254. changing= 1;change_line++;
  255. if(!input_ln(change_file)){
  256. err_print("! Change file ended before @y");
  257.  
  258. change_limit= change_buffer;changing= 0;
  259. return;
  260. }
  261. if(limit>buffer+1&&buffer[0]=='@'){
  262. if(isupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  263. /*14:*/
  264. #line 263 "wmerge.w"
  265.  
  266. if(buffer[1]=='x'||buffer[1]=='z'){
  267. loc= buffer+2;err_print("! Where is the matching @y?");
  268.  
  269. }
  270. else if(buffer[1]=='y'){
  271. if(n>0){
  272. loc= buffer+2;
  273. fprintf(stderr,"\n! Hmm... %d ",n);
  274. err_print("of the preceding lines failed to match");
  275.  
  276. }
  277. change_depth= include_depth;
  278. return;
  279. }
  280.  
  281. /*:14*/
  282. #line 247 "wmerge.w"
  283. ;
  284. }
  285. /*12:*/
  286. #line 212 "wmerge.w"
  287.  
  288. {
  289. change_limit= change_buffer-buffer+limit;
  290. strncpy(change_buffer,buffer,limit-buffer+1);
  291. }
  292.  
  293. /*:12*/
  294. #line 249 "wmerge.w"
  295. ;
  296. changing= 0;cur_line++;
  297. while(!input_ln(cur_file)){
  298. if(include_depth==0){
  299. err_print("! CWEB file ended during a change");
  300.  
  301. input_has_ended= 1;return;
  302. }
  303. include_depth--;cur_line++;
  304. }
  305. if(lines_dont_match)n++;
  306. }
  307. }
  308.  
  309. /*:13*//*15:*/
  310. #line 282 "wmerge.w"
  311.  
  312. #line 115 "wmerge.ch"
  313. void reset_input(void)
  314. #line 285 "wmerge.w"
  315. {
  316. limit= buffer;loc= buffer+1;buffer[0]= ' ';
  317. /*16:*/
  318. #line 297 "wmerge.w"
  319.  
  320. if((web_file= fopen(web_file_name,"r"))==NULL){
  321. strcpy(web_file_name,alt_web_file_name);
  322. if((web_file= fopen(web_file_name,"r"))==NULL)
  323. fatal("! Cannot open input file ",web_file_name);
  324. }
  325.  
  326.  
  327. web_file_open= 1;
  328. if((change_file= fopen(change_file_name,"r"))==NULL)
  329. fatal("! Cannot open change file ",change_file_name);
  330.  
  331. /*:16*/
  332. #line 287 "wmerge.w"
  333. ;
  334. include_depth= 0;cur_line= 0;change_line= 0;
  335. change_depth= include_depth;
  336. changing= 1;prime_the_change_buffer();changing= !changing;
  337. limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= 0;
  338. }
  339.  
  340. /*:15*//*17:*/
  341. #line 315 "wmerge.w"
  342.  
  343. get_line()
  344. {
  345. restart:
  346. if(changing&&include_depth==change_depth)
  347. /*21:*/
  348. #line 423 "wmerge.w"
  349. {
  350. change_line++;
  351. if(!input_ln(change_file)){
  352. err_print("! Change file ended without @z");
  353.  
  354. buffer[0]= '@';buffer[1]= 'z';limit= buffer+2;
  355. }
  356. if(limit>buffer){
  357. *limit= ' ';
  358. if(buffer[0]=='@'){
  359. if(isupper(buffer[1]))buffer[1]= tolower(buffer[1]);
  360. if(buffer[1]=='x'||buffer[1]=='y'){
  361. loc= buffer+2;
  362. err_print("! Where is the matching @z?");
  363.  
  364. }
  365. else if(buffer[1]=='z'){
  366. prime_the_change_buffer();changing= !changing;
  367. }
  368. }
  369. }
  370. }
  371.  
  372. /*:21*/
  373. #line 320 "wmerge.w"
  374. ;
  375. if(!changing||include_depth>change_depth){
  376. /*20:*/
  377. #line 407 "wmerge.w"
  378. {
  379. cur_line++;
  380. while(!input_ln(cur_file)){
  381. if(include_depth==0){input_has_ended= 1;break;}
  382. else{
  383. fclose(cur_file);include_depth--;
  384. if(changing&&include_depth==change_depth)break;
  385. cur_line++;
  386. }
  387. }
  388. if(!changing&&!input_has_ended)
  389. if(limit-buffer==change_limit-change_buffer)
  390. if(buffer[0]==change_buffer[0])
  391. if(change_limit>change_buffer)check_change();
  392. }
  393.  
  394. /*:20*/
  395. #line 322 "wmerge.w"
  396. ;
  397. if(changing&&include_depth==change_depth)goto restart;
  398. }
  399. loc= buffer;*limit= ' ';
  400. if(*buffer=='@'&&(*(buffer+1)=='i'||*(buffer+1)=='I')){
  401. loc= buffer+2;
  402. while(loc<=limit&&(*loc==' '||*loc=='\t'||*loc=='"'))loc++;
  403. if(loc>=limit){
  404. err_print("! Include file name not given");
  405.  
  406. goto restart;
  407. }
  408. if(include_depth>=max_include_depth-1){
  409. err_print("! Too many nested includes");
  410.  
  411. goto restart;
  412. }
  413. include_depth++;
  414. /*19:*/
  415. #line 366 "wmerge.w"
  416. {
  417. char temp_file_name[max_file_name_length];
  418. char*cur_file_name_end= cur_file_name+max_file_name_length-1;
  419. char*k= cur_file_name,*kk;
  420. int l;
  421.  
  422. while(*loc!=' '&&*loc!='\t'&&*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
  423. if(k>cur_file_name_end)too_long();
  424.  
  425. *k= '\0';
  426. if((cur_file= fopen(cur_file_name,"r"))!=NULL){
  427. cur_line= 0;
  428. goto restart;
  429. }
  430. #line 199 "wmerge.ch"
  431. if(0==set_path(include_path,getenv("CWEBINPUTS"))){
  432. include_depth--;goto restart;
  433. }
  434. path_prefix= include_path;
  435. while(path_prefix){
  436. for(kk= temp_file_name,p= path_prefix,l= 0;
  437. p&&*p&&*p!=PATH_SEPARATOR;
  438. *kk++= *p++,l++);
  439. if(path_prefix&&*path_prefix&&*path_prefix!=PATH_SEPARATOR&&
  440. *--p!=DEVICE_SEPARATOR&&*p!=DIR_SEPARATOR){
  441. *kk++= DIR_SEPARATOR;l++;
  442. }
  443. if(k+l+2>=cur_file_name_end)too_long();
  444. strcpy(kk,cur_file_name);
  445. if(cur_file= fopen(temp_file_name,"r")){
  446. cur_line= 0;goto restart;
  447. }
  448. if(next_path_prefix= strchr(path_prefix,PATH_SEPARATOR))
  449. path_prefix= next_path_prefix+1;
  450. else break;
  451. }
  452. #line 404 "wmerge.w"
  453. include_depth--;err_print("! Cannot open include file");goto restart;
  454. }
  455.  
  456. /*:19*/
  457. #line 340 "wmerge.w"
  458. ;
  459. }
  460. return(!input_has_ended);
  461. }
  462.  
  463. #line 129 "wmerge.ch"
  464. void put_line(void)
  465. {
  466. char*ptr= buffer;
  467. while(ptr<limit)
  468. {
  469. putc(*ptr,out_file);
  470. *ptr++;
  471. }
  472. putc('\n',out_file);
  473. }
  474. #line 351 "wmerge.w"
  475.  
  476. #line 153 "wmerge.ch"
  477. /*:17*//*22:*/
  478. #line 449 "wmerge.w"
  479.  
  480. #line 227 "wmerge.ch"
  481. void check_complete(void){
  482. #line 452 "wmerge.w"
  483. if(change_limit!=change_buffer){
  484. strncpy(buffer,change_buffer,change_limit-change_buffer+1);
  485. limit= buffer+(int)(change_limit-change_buffer);
  486. changing= 1;change_depth= include_depth;loc= buffer;
  487. err_print("! Change file entry did not match");
  488.  
  489. }
  490. }
  491.  
  492. /*:22*//*25:*/
  493. #line 245 "wmerge.ch"
  494.  
  495. void err_print(char*s)
  496. #line 498 "wmerge.w"
  497. {
  498. char*k,*l;
  499. fprintf(stderr,*s=='!'?"\n%s":"%s",s);
  500. if(web_file_open)/*26:*/
  501. #line 514 "wmerge.w"
  502.  
  503. {if(changing&&include_depth==change_depth)
  504. printf(". (l. %d of change file)\n",change_line);
  505. else if(include_depth==0)fprintf(stderr,". (l. %d)\n",cur_line);
  506. else fprintf(stderr,". (l. %d of include file %s)\n",cur_line,cur_file_name);
  507. l= (loc>=limit?limit:loc);
  508. if(l>buffer){
  509. for(k= buffer;k<l;k++)
  510. if(*k=='\t')putc(' ',stderr);
  511. else putc(*k,stderr);
  512. putchar('\n');
  513. for(k= buffer;k<l;k++)putc(' ',stderr);
  514. }
  515. for(k= l;k<limit;k++)putc(*k,stderr);
  516. putc('\n',stderr);
  517. }
  518.  
  519. /*:26*/
  520. #line 501 "wmerge.w"
  521. ;
  522. update_terminal;mark_error;
  523. }
  524.  
  525. /*:25*//*28:*/
  526. #line 280 "wmerge.ch"
  527.  
  528. int wrap_up(void){
  529. /*29:*/
  530. #line 553 "wmerge.w"
  531.  
  532. switch(history){
  533. case spotless:if(show_happiness)fprintf(stderr,"(No errors were found.)\n");break;
  534. case harmless_message:
  535. fprintf(stderr,"(Did you see the warning message above?)\n");break;
  536. case error_message:
  537. fprintf(stderr,"(Pardon me, but I think I spotted something wrong.)\n");break;
  538. case fatal_message:fprintf(stderr,"(That was a fatal error, my friend.)\n");
  539. }
  540.  
  541. /*:29*/
  542. #line 282 "wmerge.ch"
  543. ;
  544. switch(history){
  545. case harmless_message:return(RETURN_WARN);break;
  546. case error_message:return(RETURN_ERROR);break;
  547. case fatal_message:return(RETURN_FAIL);break;
  548. default:return(RETURN_OK);
  549. }
  550. }
  551. #line 552 "wmerge.w"
  552.  
  553. /*:28*//*33:*/
  554. #line 326 "wmerge.ch"
  555.  
  556. void scan_args(void)
  557. #line 606 "wmerge.w"
  558. {
  559. char*dot_pos;
  560. char*name_pos;
  561. register char*s;
  562. boolean found_web= 0,found_change= 0,found_out= 0;
  563.  
  564. boolean flag_change;
  565.  
  566. while(--argc>0){
  567. if(**(++argv)=='-'||**argv=='+')/*37:*/
  568. #line 674 "wmerge.w"
  569.  
  570. {
  571. if(**argv=='-')flag_change= 0;
  572. else flag_change= 1;
  573. for(dot_pos= *argv+1;*dot_pos>'\0';dot_pos++)
  574. flags[*dot_pos]= flag_change;
  575. }
  576.  
  577. /*:37*/
  578. #line 615 "wmerge.w"
  579.  
  580. else{
  581. s= name_pos= *argv;dot_pos= NULL;
  582. while(*s){
  583. if(*s=='.')dot_pos= s++;
  584. else if(*s=='/')dot_pos= NULL,name_pos= ++s;
  585. else s++;
  586. }
  587. if(!found_web)/*34:*/
  588. #line 640 "wmerge.w"
  589.  
  590. {
  591. if(s-*argv>max_file_name_length-5)
  592. /*39:*/
  593. #line 687 "wmerge.w"
  594. fatal("! Filename too long\n",*argv);
  595.  
  596. /*:39*/
  597. #line 643 "wmerge.w"
  598. ;
  599. if(dot_pos==NULL)
  600. sprintf(web_file_name,"%s.w",*argv);
  601. else{
  602. strcpy(web_file_name,*argv);
  603. *dot_pos= 0;
  604. }
  605. sprintf(alt_web_file_name,"%s.web",*argv);
  606. *out_file_name= '\0';
  607. found_web= 1;
  608. }
  609.  
  610. /*:34*/
  611. #line 623 "wmerge.w"
  612.  
  613. else if(!found_change)/*35:*/
  614. #line 655 "wmerge.w"
  615.  
  616. {
  617. if(s-*argv>max_file_name_length-4)
  618. /*39:*/
  619. #line 687 "wmerge.w"
  620. fatal("! Filename too long\n",*argv);
  621.  
  622. /*:39*/
  623. #line 658 "wmerge.w"
  624. ;
  625. if(dot_pos==NULL)
  626. sprintf(change_file_name,"%s.ch",*argv);
  627. else strcpy(change_file_name,*argv);
  628. found_change= 1;
  629. }
  630.  
  631. /*:35*/
  632. #line 624 "wmerge.w"
  633.  
  634. else if(!found_out)/*36:*/
  635. #line 665 "wmerge.w"
  636.  
  637. {
  638. if(s-*argv>max_file_name_length-5)
  639. /*39:*/
  640. #line 687 "wmerge.w"
  641. fatal("! Filename too long\n",*argv);
  642.  
  643. /*:39*/
  644. #line 668 "wmerge.w"
  645. ;
  646. if(dot_pos==NULL)sprintf(out_file_name,"%s.out",*argv);
  647. else strcpy(out_file_name,*argv);
  648. found_out= 1;
  649. }
  650.  
  651. /*:36*/
  652. #line 625 "wmerge.w"
  653.  
  654. else/*38:*/
  655. #line 682 "wmerge.w"
  656.  
  657. {
  658. fatal("! Usage: wmerge webfile[.w] [changefile[.ch] [outfile[.out]]]\n","")
  659. }
  660.  
  661. /*:38*/
  662. #line 626 "wmerge.w"
  663. ;
  664. }
  665. }
  666. if(!found_web)/*38:*/
  667. #line 682 "wmerge.w"
  668.  
  669. {
  670. fatal("! Usage: wmerge webfile[.w] [changefile[.ch] [outfile[.out]]]\n","")
  671. }
  672.  
  673. /*:38*/
  674. #line 629 "wmerge.w"
  675. ;
  676. #line 333 "wmerge.ch"
  677. #if defined( __TURBOC__ )
  678. if(!found_change)strcpy(change_file_name,"nul");
  679. #elif defined( _AMIGA )
  680. if(!found_change)strcpy(change_file_name,"NIL:");
  681. #else
  682. if(!found_change)strcpy(change_file_name,"/dev/null");
  683. #endif
  684. #line 631 "wmerge.w"
  685. }
  686.  
  687. /*:33*//*43:*/
  688. #line 352 "wmerge.ch"
  689.  
  690. static boolean set_path(char*ptr,char*override)
  691. {
  692. if(override){
  693. if(strlen(override)>=MAXPATHLENGTH){
  694. err_print("! Include path too long");return(0);
  695.  
  696. }
  697. else strcpy(ptr,override);
  698. }
  699. return(1);
  700. }
  701.  
  702. /*:43*/
  703. #line 19 "wmerge.w"
  704.  
  705. main(ac,av)
  706. int ac;char**av;
  707. {
  708. argc= ac;argv= av;
  709. /*31:*/
  710. #line 583 "wmerge.w"
  711.  
  712. show_banner= show_happiness= 1;
  713.  
  714. /*:31*/
  715. #line 24 "wmerge.w"
  716. ;
  717. /*41:*/
  718. #line 695 "wmerge.w"
  719.  
  720. scan_args();
  721. if(out_file_name[0]=='\0')out_file= stdout;
  722. else if((out_file= fopen(out_file_name,"w"))==NULL)
  723. fatal("! Cannot open output file ",out_file_name);
  724.  
  725.  
  726. /*:41*/
  727. #line 25 "wmerge.w"
  728. ;
  729. reset_input();
  730. while(get_line())
  731. put_line();
  732. fflush(out_file);
  733. check_complete();
  734. fflush(out_file);
  735. return wrap_up();
  736. }
  737.  
  738. /*:1*/
  739.